home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / ghostscript / 8.64 / Resource / Init / pdf_font.ps < prev    next >
Encoding:
Text File  |  2009-04-17  |  57.5 KB  |  1,710 lines

  1. %    Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: pdf_font.ps 9330 2009-01-07 08:33:14Z ken $
  14. % PDF font operations.
  15.  
  16. % Since PDF font are not unique and can collide with external font resources
  17. % or each other, use font dictionaries obtained from PDF directly, never
  18. % register them as resources or look them up by name. Use findfont oparator
  19. % for non-embedded fonts only. CIDFont resources still use the old logic
  20. % described below.
  21.  
  22. % Finding a font by name can't give a proper result when PDF font names aren't unique.
  23. % But it is only the way to obtain a font in Postscript after a font file is executed.
  24. % Therefore using a FontName (and findfont) is allowed only
  25. % immediately after a font file is executed.
  26. % In all other cases the font to be found by a pointer through PDF structures.
  27. %
  28. % This ideal logics can't work for documents,
  29. % which define a font resource with an embedded font,
  30. % and another font resource with same BaseFont but with no embedded font
  31. % (and possibly with no font descriptor).
  32. % Our testbase does contain such examples.
  33. % In this case we do find font by FontName (with findfont),
  34. % since there is no other way to get a reasonable result.
  35.  
  36. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  37. .currentglobal true .setglobal
  38. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  39. GS_PDF_ProcSet begin
  40. pdfdict begin
  41.  
  42. % We cache the PostScript font in an additional element of the
  43. % font resource dictionary, called PSFont.
  44.  
  45. % ---------------- Encodings ---------------- %
  46.  
  47. /.notdefEncoding 256 { /.notdef } repeat 256 packedarray def
  48.  
  49. % Apply a list of differences to an Encoding.
  50. % Note that the differences may cause the array to grow.
  51. /updateencoding {    % <encoding|null> <differences> updateencoding <enc'>
  52.     % Calculate the length of the result.
  53.   % in case the incoming Encoding is null, use .notdefEncoding
  54.   exch dup null eq { pop .notdefEncoding } if
  55.   0 0 3 index {
  56.     dup type /nametype ne { exch pop oforce } { pop 1 add } ifelse
  57.     % Differences list may not be in order, update the largest_index
  58.     % stack: <Differences> <encoding> <largest_index> <at_index>
  59.     2 copy lt { exch pop dup } if    % at_index is new largest
  60.   } forall
  61.   pop 1 index length .max array dup 0 4 -1 roll putinterval
  62.   exch 0 exch {
  63.         % Stack: enc' code element
  64.     dup type /nametype ne
  65.       { exch pop oforce }
  66.       { 3 copy put pop 1 add }
  67.     ifelse
  68.   } forall pop
  69. } bdef
  70.  
  71. /good_encoding_names <<
  72.   /MacRomanEncoding 0 /MacExpertEncoding 0 /WinAnsiEncoding 0
  73. >> readonly def
  74.  
  75. /known_symbolic_fonts <<
  76.   /Wingdings2 0
  77. >> readonly def
  78.  
  79. % Get the Encoding for a font.
  80. /getencoding        % <base-encoding> <font-resource> getencoding <enc>
  81.  { dup /Encoding knownoget
  82.     { dup type /nametype eq
  83.        {
  84.          % The published PDF specification says the Encoding name
  85.          % "must be" one of the 3 predefined Encodings, implying
  86.          % that an error should occur if it isn't.  However, Acrobat
  87.          % Reader simply ignores unknown names, and since there are
  88.          % some buggy applications that rely on this, we do the same.
  89.  
  90.          //good_encoding_names 1 index known {
  91.            exch /BaseFont knownoget not { 0 } if 
  92.            % Ignore named encodings for known symbolic fonts. See bug 690135.
  93.            //known_symbolic_fonts exch known {
  94.              pop
  95.            } {
  96.              exch pop findencoding
  97.            } ifelse
  98.          } {
  99.            pop pop
  100.          } ifelse
  101.        }
  102.        { exch pop
  103.          dup type /arraytype eq
  104.      { exch pop
  105.        (   **** Warning: Encoding is an array, not name or dictionary.\n)  pdfformaterror
  106.      }
  107.      { dup /BaseEncoding knownoget
  108.          { dup / eq
  109.          { pop
  110.            (   **** Warning: Ignoring bad BaseEncoding name.\n)  pdfformaterror
  111.            % as found in a PDF file from J.D.Edwards OneWorld (B7333), bug 687786
  112.          }
  113.          { findencoding 3 -1 roll pop exch }
  114.            ifelse
  115.          }
  116.        if
  117.        /Differences knownoget { updateencoding } if
  118.      }
  119.      ifelse
  120.        }
  121.        ifelse
  122.      } {
  123.        pop
  124.        (   **** Warning: Encoding not present.\n)  pdfformaterror
  125.      }
  126.      ifelse
  127.  } bdef
  128.  
  129. currentdict /good_encoding_names undef
  130. currentdict /known_symbolic_fonts undef
  131.  
  132. /checkGlyphNames2Unicode % <dict> checkGlyphNames2Unicode -
  133. {
  134.   PDFDEBUG {
  135.     dup /FontInfo .knownget { 
  136.       /GlyphNames2Unicode .knownget { 
  137.         (Has GlyphNames2Unicode) =
  138.         pop % { exch == ==} forall 
  139.       } if 
  140.     } if
  141.   } if
  142.   pop
  143. } bind def
  144.  
  145. % Define a font using it's FontName as the key.
  146. % Adjust a font according to the Encoding and Widths in the font resource.
  147. /adjustfont {        % <font-resource> <font> adjustfont <font'>
  148.   getfontencoding
  149.   3 copy .processToUnicode
  150.   getfontmetrics 5 -1 roll pop .updatefont { .completefont } if
  151. } bind def
  152.  
  153. % Get the (possibly modified) encoding of a font.
  154. /getfontencoding {    % <font-resource> <font> getfontencoding
  155.             %   <font-resource> <font> <Encoding|null>
  156.   //systemdict /IgnoreTTEncoding .knownget not { //false } if {
  157.   1 index /Subtype get /TrueType eq } { //false } ifelse {
  158.     //null
  159.   } {
  160.     1 index /Encoding known {
  161.       dup /Encoding knownoget { 2 index getencoding } { //null } ifelse
  162.     } {
  163.       //null
  164.     } ifelse
  165.   } ifelse
  166. } bdef
  167.  
  168. % Returns true if the current glyph is in the Differences array at
  169. % the specified index value. This is needed because the Widths
  170. % array may map to the same glyph at different positions from the
  171. % Encoding. We want to use the Width that was associated with the
  172. % one specified in the Encoding::Differences list.
  173. /match_in_diff     % <Differences> <index> <glyphname> match_in_diff <bool>
  174. { false 4 1 roll 0 4 -1 roll    % stack: false index glyphname at_index==0 Differences
  175.   { exch 1 index type /nametype ne {
  176.       % stack: false index glyphname Diff_element at_index 
  177.       pop    % Diff_element is new at_index
  178.     } {
  179.       % stack: false index glyphname Diff_element at_index 
  180.       exch 2 index eq {
  181.         % stack: false index glyphname at_index 
  182.     dup 3 index eq {
  183.           true 5 1 roll    % stack: true false index glyphname at_index
  184.           pop exit
  185.         } if
  186.       } if
  187.       1 add        % at_index++ stack: false index glyphname at_index' 
  188.     } ifelse
  189.   } forall
  190.   % stack: true  false index     glyphname
  191.   %  or  : false index glyphname at_index
  192.   pop pop pop
  193. } bdef
  194.  
  195. /unique_name {  % <dict> </root> unique_name </unique> 
  196.   %
  197.   %  Note : this function interacts with pdf_write_encoding in src/gdevpdtw.c
  198.   %  and with copied_drop_extension_glyphs in src\gxfcopy.c
  199.   %  by adding a reserved substring (~GS~).
  200.   %
  201.   .namestring       % <<>> (root)
  202.   0 1 65535 {
  203.     5 string cvs    % <<>> (root) (0)
  204.     (~GS~) exch concatstrings
  205.     1 index exch    % <<>> (root) (root) (~GS~0)
  206.     concatstrings   % <<>> (root) (root~GS~0)
  207.     dup             % <<>> (root) (root~GS~0) (root~GS~0)
  208.     3 index exch    % <<>> (root) (root~GS~0) <<>> (root~GS~0)
  209.     known not {
  210.       exch pop exit % <<>> (root~GS~0)
  211.     } if
  212.     pop
  213.   } for
  214.   exch pop cvn      % /root0
  215. } bdef
  216.                                
  217. % Get the metrics of a font, if specified.
  218. /getfontmetrics {       % <font-resource> <font> <Encoding|null> getfontmetrics
  219.                         %   <font-resource> <font> <Encoding|null>
  220.                         %   <Metrics|null> <GlyphMap|null>
  221.  
  222.   2 index /Widths known {
  223.     dup //null eq { pop dup /Encoding get } if
  224.     7 dict begin
  225.       dup length dict
  226.       /Metrics exch def
  227.       /Encoding exch def
  228.       /GlyphMap //null def
  229.       exch
  230.       dup /Widths oget /Widths exch def
  231.                 % Stack: font font-res
  232.                 % Note that widths are always based on a 1000-unit
  233.                 % character space, but the FontMatrix may specify
  234.                 % some other scale factor.  Compensate for this here,
  235.                 % by scaling the Widths if necessary.
  236.       0.001 2 index /FontMatrix get 0 get
  237.       dup 0 eq {
  238.         % FontMatrix.xx == 0, so we cannot scale down by xx.
  239.         % - FontMatrix[0] == 0 implies either FontMatrix[1] <> 0 or 
  240.         %   FontMatrix cannot be inverted. In the 1st case we have 
  241.         %   FontMatrixNonHV == true and will render text with cshow + xshow. 
  242.         %   In the 2nd case, metrics in the PDF Font object cannot be enforced 
  243.         %   [by altering metrics in PS glyph space].
  244.         % HACK:
  245.         % - we scale down by FontMatrix[1];
  246.         % - given the format of Metrics entries we use, wy = 0 in glyph space;
  247.         % - as a result, the cshow procedure receives as wy the value we 
  248.         %   need for wx (all of this in PS user space).
  249.     pop
  250.     2 index /FontMatrix get 1 get
  251.     dup 0 eq { pop 1 } if % sorry, no way to enforce PDF metrics by altering the font
  252.       } if
  253.       div
  254.                 % Stack: font font-res mscale
  255.       /FirstChar 2 index /FirstChar oget def
  256.       /LastChar  2 index /LastChar  oget def
  257.  
  258.       Encoding length LastChar le {
  259.          (   **** Warning: Font Encoding array size is smaller than character range.\n)
  260.          pdfformaterror
  261.       } if
  262.  
  263.       1 index /FontDescriptor knownoget {
  264.            /MissingWidth knownoget not { 0 } if 
  265.         } 
  266.         { 1000 
  267.         } 
  268.       ifelse /MissingWidth exch def
  269.              
  270.       Widths length LastChar FirstChar sub le {
  271.          (   **** Warning: Font Widths array size is smaller than character range.\n)
  272.          pdfformaterror
  273.          /Widths [Widths aload length LastChar FirstChar sub exch sub MissingWidth exch {dup} repeat] def
  274.       } if
  275.       FirstChar
  276.  
  277.       0 Encoding 
  278.        {        % Stack: font font-res mscale first-char index charname
  279.  
  280.          1 index FirstChar lt { MissingWidth } {
  281.            1 index LastChar gt { MissingWidth } { Widths 2 index FirstChar sub get } ifelse
  282.          } ifelse
  283.  
  284.                 % Stack: font font-res mscale first-char index charname width
  285.          4 index mul
  286.                 % The following 'loop' is only context for 'exit'.
  287.          {      
  288.                 % Work around a bug in pdfTeX, which can generate Encoding
  289.                 % vectors containing nulls :
  290.            1 index //null eq { exit } if
  291.            Metrics 2 index .knownget {
  292.              1 index ne
  293.            } {
  294.              //false
  295.            } ifelse {
  296.              % Two or more Encoding elements refer same glyph name,
  297.              % and Widths specify different wihts for it.
  298.              % Since a Postscript font can't have different 
  299.              % Metrics for same glyph name, 
  300.              % we generate an unique name, and create a new 
  301.              % Charstrings entry with same glyph value.
  302.              GlyphMap //null eq {
  303.                /Encoding Encoding dup length array copy def
  304.                /GlyphMap 4 dict def
  305.              } if
  306.              % To prevent too many new names, check whether
  307.              % we can use one already created for same glyph.
  308.              //true
  309.              GlyphMap {                           % f r s c i n w b n1 n2
  310.                4 index eq {                       % f r s c i n w b n1
  311.                  dup Metrics exch get             % f r s c i n w b n1 w1
  312.                  3 index eq {                     % f r s c i n w b n1
  313.                    4 3 roll pop                   % f r s c i w b n1
  314.                    3 1 roll pop                   % f r s c i n1 w
  315.                    Encoding 3 index 3 index put
  316.                    //false                        % f r s c i n1 w b
  317.                    exit
  318.                  } {
  319.                    pop
  320.                  } ifelse
  321.                } {                                % f r s c i n w b n1
  322.                  pop
  323.                } ifelse
  324.              } forall                             % f r s c i n w b
  325.              { % Do create a new name.
  326.                Metrics 2 index //unique_name exec % f r s c i n w nn
  327.                Encoding 4 index 2 index put
  328.                GlyphMap 1 index 5 -1 roll put     % f r s c i w nn
  329.                exch
  330.                   % Stack: font font-res mscale first-char index new_name width
  331.              } if
  332.            } if
  333.            2 copy Metrics 3 1 roll put
  334.            exit
  335.          } loop
  336.          pop pop
  337.          1 add
  338.        }
  339.      forall pop pop pop
  340.      exch Encoding Metrics GlyphMap end
  341.   } {
  342.     //null //null
  343.   } ifelse
  344. } bdef
  345.  
  346. currentdict /unique_name undef
  347. currentdict /match_in_diff undef
  348.  
  349. /ToUnicodeCMapReader 3 dict begin
  350.   /defineresource % <name> <dict> <cat-name> defineresource <dict> 
  351.   {
  352.     pop 
  353.     dup userdict exch /.lastToUnicode exch put
  354.     exch pop
  355.   } bind def
  356.   /CIDSystemInfo 
  357.   { 
  358.     (   **** Warning: ToUnicode CMap has invalid syntax near CIDSystemInfo.\n)  pdfformaterror
  359.     /CIDSystemInfo 
  360.   } bind def % A work around a bug in Altona.Page_3.2002-09-27.pdf - a slash is missed.
  361.   /CMapName
  362.   {
  363.     (   **** Warning: ToUnicode CMap has no CMapName.\n\
  364.         See the comment to revision 6201 in gs/doc/ps2pdf.htm#Problems .\n) pdfformaterror
  365.     /CMap1   % arbitrary, PDF defineresource tolerates non-unique names
  366.   } bind def % A work around incorrect ToUnicode CMap generated by GS before rev. 6201.
  367. currentdict end readonly def
  368.  
  369. /string2number     % <string> string2number <number>
  370. { 0 exch dup 0 exch 1 exch length 1 sub {     % n () i
  371.     1 index exch get                          % n () v
  372.     3 2 roll 256 mul add exch                 % v+n*256 ()
  373.   } for
  374.   pop                                         % N
  375. } bind def
  376.  
  377. /copy&def    % <key> <value> <bool> copy&def -
  378. {
  379.   { true
  380.   } {
  381.     currentdict gcheck { 
  382.       dup gcheck not
  383.     } {
  384.       false
  385.     } ifelse
  386.   } ifelse
  387.   { currentglobal currentdict gcheck setglobal 
  388.     exch dup length string copy exch 
  389.     setglobal
  390.   } if
  391.   def
  392. } bind def
  393.  
  394. /.convert_ToUnicode-into-g2u % <GlyphNames2Unicode> <Encoding|null> <CMap> .convert_ToUnicode-into-g2u -
  395. {
  396.   PDFDEBUG {
  397.     (.convert_ToUnicode-into-g2u beg) =
  398.   } if
  399.   3 2 roll begin
  400.   /.CodeMapData get % About the data format see gs_cmap.ps, the comment after "CMap operators".
  401.   1 get % code maps
  402.   { 
  403.     PDFDEBUG {
  404.       dup ==
  405.     } if
  406.     dup length 1 sub 0 exch 5 exch {           % e [] i
  407.       2 copy get                               % e [] i (prefix)
  408.       string2number                            % e [] i prefix
  409.       2 index 2 index 1 add get                % e [] i prefix (key_size,?is_range,value_type,value_size)
  410.       dup 0 get 8 mul                          % e [] i prefix (key_size,?is_range,value_type,value_size) key_size*8
  411.       3 2 roll exch bitshift exch              % e [] i prefix<<key_size*8 (key_size,?is_range,value_type,value_size)
  412.       dup 0 get exch 3 get                     % e [] i offset key_size value_size
  413.       4 index 4 index 2 add get                % e [] i offset key_size value_size (keys)
  414.       5 index 5 index 3 add get                % e [] i offset key_size value_size (keys) (values)
  415.       PDFDEBUG {
  416.         ( offset=) print 4 index =string cvs print
  417.         ( key_size=) print 3 index =string cvs print
  418.         ( value_size=) print 2 index =
  419.         ( keys=)   print 1 index ==
  420.         ( values=) print dup ==
  421.       } if
  422.       1 index length 0 eq {
  423.         % A single pair.
  424.         exch pop exch pop exch pop exch        % e [] i (values) offset
  425.         4 index null ne {
  426.           4 index length 1 index gt {
  427.             4 index exch get
  428.           } if
  429.         } if                                   % e [] i (values) cid|name
  430.         exch 
  431.         PDFDEBUG {
  432.           ( defined single: ) print 1 index =string cvs print ( ) print dup ==
  433.         } if
  434.         false copy&def                         % e [] i
  435.         pop                                    % e []
  436.       } {
  437.         % A range.                             % e [] i offset key_size value_size (keys) (values)
  438.         dup length string copy % protect the original string from modifications below.
  439.         0 4 index 2 mul 3 index length 1 sub { % e [] i offset key_size value_size (keys) (values) j
  440.           2 index 1 index 6 index getinterval          
  441.           string2number                        % e [] i offset key_size value_size (keys) (values) j keyL
  442.           PDFDEBUG {
  443.               ( keyL=) print dup =string cvs print
  444.           } if
  445.           3 index 2 index 7 index add 7 index getinterval
  446.           string2number                        % e [] i offset key_size value_size (keys) (values) j keyL keyH
  447.           PDFDEBUG {
  448.               ( keyH=) print dup =
  449.           } if
  450.           3 2 roll 6 index idiv 5 index mul    % e [] i offset key_size value_size (keys) (values) keyL keyH J
  451.           3 index exch 6 index getinterval     % e [] i offset key_size value_size (keys) (values) keyL keyH (valueL)
  452.           3 1 roll 1 exch {                    % e [] i offset key_size value_size (keys) (values) (value) k
  453.             9 index null ne {
  454.               9 index exch get                 % e [] i offset key_size value_size (keys) (values) (value) name
  455.             } if                               % e [] i offset key_size value_size (keys) (values) (value) cid|name
  456.             1 index                            % e [] i offset key_size value_size (keys) (values) (value) cid|name (value)
  457.             PDFDEBUG {
  458.               ( defined from range: ) print 1 index =string cvs print ( ) print dup ==
  459.             } if
  460.             true copy&def                      % e [] i offset key_size value_size (keys) (values) (value)
  461.             % Assuming the lowest byte of 'value' changes, others don't.
  462.             dup dup length 1 sub               % e [] i offset key_size value_size (keys) (values) (value) (value) l
  463.             2 copy get                         % e [] i offset key_size value_size (keys) (values) (value) (value) l v
  464.             % Modulo 256 increment prevents a rangecheck error when the result is stored in a string.
  465.             % The adjustment can happen only at the end of the loop where the string is discarded. Bug 688535.
  466.             1 add 255 and put                  % e [] i offset key_size value_size (keys) (values) (value')
  467.           } for                                % e [] i offset key_size value_size (keys) (values) (value)
  468.         } for
  469.         pop pop pop pop pop pop pop            % e []
  470.       } ifelse
  471.     } for
  472.     pop                                        % e
  473.   } forall
  474.   end
  475.   pop                                          %
  476.   PDFDEBUG {
  477.     (.convert_ToUnicode-into-g2u end) =
  478.   } if
  479. } bind def
  480.  
  481. /.processToUnicode   % <font-resource> <font-dict> <encoding|null> .processToUnicode -
  482. {
  483.   % Currently pdfwrite is only device which can handle GlyphNames2Unicoide to 
  484.   % generate a ToUnicode CMaps. So don't bother with other devices.
  485.   currentdevice .devicename /pdfwrite eq {
  486.     PDFDEBUG {
  487.       (.processToUnicode beg) =
  488.     } if
  489.     2 index /ToUnicode knownoget {
  490.       dup type /dicttype eq { dup /File known not } { //true } ifelse {
  491.         % We undefine wrong /Length and define /File in stream dictionaries.
  492.         % Bug687351.pdf defines /ToUnicode /Identity-H, what is incorrect.
  493.         (   **** Warning: Ignoring bad ToUnicode CMap.\n)  pdfformaterror
  494.         pop
  495.       } {
  496.  
  497.         /PDFScanRules .getuserparam dup //null eq {
  498.           pop //PDFScanRules_null
  499.         } {
  500.           1 dict dup /PDFScanRules 4 -1 roll put
  501.         } ifelse
  502.         //PDFScanRules_true setuserparams
  503.         PDFfile fileposition 3 -1 roll
  504.  
  505.         //false resolvestream
  506.         //ToUnicodeCMapReader begin
  507.            % Following Acrobat we ignore everything outside
  508.            %   begincodespacerange .. endcmap.
  509.            dup 0 (begincodespacerange) /SubFileDecode filter flushfile
  510.            /CIDInit /ProcSet findresource begin 12 dict begin
  511.            /CMapType 2 def
  512.            mark exch % emulate 'begincodespacerange'
  513.            0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn
  514.            endcmap 
  515.            userdict /.lastToUnicode currentdict put
  516.         end end end
  517.  
  518.         PDFfile exch setfileposition
  519.         setuserparams
  520.  
  521.         1 index /FontInfo .knownget not {
  522.           currentglobal 2 index dup gcheck setglobal
  523.           /FontInfo 5 dict dup 5 1 roll .forceput
  524.           setglobal
  525.         } if
  526.         dup /GlyphNames2Unicode .knownget not {
  527.           true                    % No existing G2U, make one
  528.         } {
  529.           dup wcheck {
  530.             false                % Existing, writeable G2U, don't make new one
  531.           } {
  532.             pop true                % Existing read only G2U, make new one
  533.           } ifelse
  534.         } ifelse
  535.  
  536.         {
  537.           currentglobal exch dup gcheck setglobal
  538.           dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput
  539.           3 2 roll setglobal
  540.         } if                                 % font-res font-dict encoding|null font-info g2u
  541.         exch pop exch                        % font-res font-dict g2u encoding|null
  542.         userdict /.lastToUnicode get         % font-res font-dict g2u Encoding|null CMap
  543.         .convert_ToUnicode-into-g2u          % font-res font-dict
  544.         //null                               % font-res font-dict null
  545.       } ifelse
  546.     } if
  547.     PDFDEBUG {
  548.       (.processToUnicode end) =
  549.     } if
  550.   } if
  551.   pop pop pop
  552. } bind def
  553.  
  554. % ---------------- Descriptors ---------------- %
  555.  
  556. % Partial descriptors for the 14 built-in fonts.  Note that
  557. % from PDF 1.1 to PDF 1.2, the meaning of the Flag 6 in the FontDescriptor
  558. % object has undergone a subtle change in its meaning which has serious
  559. % consequences for searching with Acrobat:
  560. % In PDF 1.1, the flag meant: Font has StandardEncoding
  561. % In PDF 1.2, the flag means: Font has (subset of) StandardRomanCharacterSet
  562. /standardfontdescriptors mark
  563.   /Courier mark /Flags 16#23 .dicttomark
  564.   /Courier-Oblique 1 index
  565.   /Courier-Bold 1 index
  566.   /Courier-BoldOblique 1 index
  567.   /Helvetica mark /Flags 16#20 .dicttomark
  568.   /Helvetica-Oblique 1 index
  569.   /Helvetica-Bold 1 index
  570.   /Helvetica-BoldOblique 1 index
  571.   /Times-Roman mark /Flags 16#22 .dicttomark
  572.   /Times-Bold 1 index
  573.   /Times-Italic mark /Flags 16#62 .dicttomark
  574.   /Times-BoldItalic 1 index
  575.   /Symbol mark /Flags 16#4 .dicttomark
  576.   /ZapfDingbats 1 index
  577. .dicttomark readonly def
  578.  
  579. % ---------------- Utilities ---------------- %
  580.  
  581.  
  582. /.pdforigfontcache_g 20 dict def
  583. currentglobal false setglobal
  584. systemdict /.pdforigfontcache_l 20 dict .forceput
  585. setglobal
  586.  
  587. % Find an original font, using cache to prevent adjustfont to accumulate changes.
  588. /pdffindcachedfont {   % <font_name> pdffindcachedfont <font>
  589.   dup //.pdforigfontcache_g exch .knownget {
  590.     exch pop
  591.   } {
  592.     dup .pdforigfontcache_l exch .knownget {
  593.       exch pop
  594.     } {
  595.       dup findfont dup    
  596.       dup gcheck { //.pdforigfontcache_g } { .pdforigfontcache_l } ifelse
  597.                      % Stack : font_name font font cache
  598.       4 2 roll .growput
  599.     } ifelse
  600.   } ifelse
  601. } bind def
  602.  
  603. % Add original font to cache to prevent adjustfont to accumulate changes.
  604. /pdfaddcachedfont {   % <font_name> pdfaddcachedfont <font>
  605.   dup findfont dup                   % name font font
  606.   dup gcheck { //.pdforigfontcache_g } {.pdforigfontcache_l} ifelse
  607.   4 2 roll                           % font d name font
  608.   put                                % font
  609. } bind def
  610.  
  611. /.remove_font_name_prefix {  % <name>  .remove_font_name_prefix <name>
  612.   dup .namestring (+) search {
  613.     true exch
  614.     { dup 65 lt exch 90 gt or {
  615.         pop false exit
  616.       } if
  617.     } forall
  618.     { pop exch pop cvn
  619.     } {
  620.       pop pop
  621.     } ifelse
  622.   } {
  623.     pop
  624.   } ifelse
  625. } bind def
  626.  
  627. % Find a font (except for embedded ones), and adjust its encoding if necessary.
  628. /.pdfdfndict mark
  629.   /defaultfontname /Helvetica
  630. .dicttomark readonly def
  631. /pdffindfont {        % <font-resource> <fontname> pdffindfont <font>
  632.         % If the font isn't available, synthesize one based on
  633.         % its descriptor.
  634.   dup /Font resourcestatus {
  635.     pop pop pdffindcachedfont
  636.   } {
  637.     1 index /FontDescriptor knownoget {
  638.         % Stack: font-res fontname fontdesc
  639.       dup /Flags oget
  640.       dup 16#40 and -6 bitshift        % 1, oblique/italic
  641.       1 index 16#40000 and -17 bitshift add    % 2, bold
  642.       exch 16#2 and 2 bitshift add    % 8, serif
  643.         % We should look at the fixed flag, too.
  644.         % Stack: font-res fontname fontdesc properties
  645.  
  646.                 % Even though /FontName is a required key in FontDescriptor dict
  647.                 % (As of the PDF 1.4 Reference Manual), In the case of missing 
  648.                 % /FontName key, we substitue /BaseFont for the value of /FontName.
  649.                 % Yet another case of broken PDF's that Adobe Reader accepts.
  650.       1 index dup /FontName known {
  651.         /FontName oget
  652.       } {
  653.         (   **** FontDescriptor missing required /FontName key. BaseFont name used.\n)
  654.         pdfformaterror
  655.         pop 2 index        % grab the BaseFont from the stack.
  656.       } ifelse
  657.       .remove_font_name_prefix
  658.       exch
  659.         % Analyzes font name and extract "Bold" and "Narrow" properties
  660.         % which are not described by the FontDescriptor Flags.
  661.       0 2 index .fontnameproperties 6 and or
  662.         % Rebind the default font name to Helvetica so that
  663.         % fonts with no properties are handled correctly.
  664.       //.pdfdfndict begin .substitutefontname end
  665.         % Stack: font-res fontname fontdesc substname|null
  666.       Fontmap 1 index known not {
  667.         % No available good substitution, use the standard one.
  668.     pop 1 index .substitutefont
  669.       } if
  670.       dup 3 index ne QUIET not and {
  671.     (Substituting font ) print dup =only
  672.     ( for ) print 2 index =only (.) = flush
  673.       } if
  674.       pdffindcachedfont
  675.         % Stack: font-res fontname fontdesc font
  676.         % If this is a small-caps font, replace the CharString
  677.         % entries for a..z.
  678.       exch /Flags oget 16#20000 and 0 ne {
  679.     true .copyfontdict
  680.     dup /CharStrings 2 copy get dup length dict .copydict
  681.     % stack: font-res fontname font font /CharStrings CharStringsdict
  682.     5 index /FirstChar get 97 .max
  683.     6 index /LastChar get 122 .min 1 exch {
  684.         % Stack: font-res fontname font' font' /CharStrings charstrings code
  685.         % Note that this only remaps a-z, not accented characters.
  686.       6 index /Widths oget 1 index 8 index /FirstChar get sub oget
  687.       1 string dup 0 5 -1 roll put
  688.         % Stack: font-res font' font' /CharStrings charstrings code
  689.         %   width (x)
  690.       2 index exch dup cvn exch
  691.       dup 0 2 copy get 32 sub put 4 -1 roll {
  692.             % Stack: operand (X) width
  693.         0 setcharwidth exch pop
  694.         currentfont /FontMatrix get matrix invertmatrix concat
  695.         0.7 dup scale 0 0 moveto show
  696.       } /exec cvx 4 packedarray cvx put
  697.     } for put
  698.       } if
  699.       dup /FontName get 2 index ne {
  700.         true .copyfontdict
  701.         2 copy exch /FontName exch put
  702.       } if
  703.       exch pop .completefont
  704.     } {
  705.         % No descriptor available, use the default algorithm.
  706.       pdffindcachedfont
  707.     } ifelse
  708.   } ifelse
  709.   exch pop
  710. } bdef
  711.  
  712. % ---------------- Type 1 fonts ---------------- %
  713.  
  714. /buildType1        % <Type1-font-resource> buildType1 <font>
  715.  { dup /BaseFont get pdffindfont
  716.  } bdef
  717.  
  718. % Read an embedded Type 1 font.
  719. /readfontfilter {    % <proc> readfontfilter <filter>
  720.   0 () /SubFileDecode filter
  721. } bdef
  722.  
  723. % Adobe Acrobat doesn't skip space characters after eexec
  724. /eexec_pdf_param_dict mark
  725.   .eexec_param_dict {} forall
  726.   /keep_spaces true
  727. .dicttomark readonly def
  728.  
  729. % When Type 1 font reading procedure is executing, a copy of this dictionary is current.
  730. % We have to do something special about embedded fonts that execute definefont
  731. % more than once -- that is the function of topFontDict.
  732. % The whole type1 stream can be executed directly. There's no need to process
  733. % Length1, 2, 3 keys.
  734.  
  735. /readtype1dict 5 dict dup begin
  736.   /definefont {
  737.     exch pop
  738.     dup /UniqueID .knownget {
  739.       dup dup 0 lt exch 16#ffffff gt or {
  740.         (   **** Warning: Ignoring invalid /UniqueID = ) exch =string cvs
  741.         concatstrings (\n) concatstrings pdfformaterror
  742.         dup /UniqueID undef
  743.       } {
  744.         pop
  745.       } ifelse
  746.     } if
  747.     .completefont
  748.   } bdef
  749.  
  750.   /undef_proc_warning {
  751.     /Repaired true store    % flag that we have warnings
  752.     UndefProcList exch 2 copy .knownget { 1 add } { 1 } ifelse put
  753.   } bdef
  754.  
  755.   /missing-type1-procs 6 dict begin
  756.     /-| { string currentfile exch readstring pop /-| //undef_proc_warning exec } executeonly bdef
  757.     /RD { string currentfile exch readstring pop /RD //undef_proc_warning exec } executeonly bdef
  758.     /|- { noaccess def /|- //undef_proc_warning exec } executeonly bdef
  759.     /ND { noaccess def /ND //undef_proc_warning exec } executeonly bdef
  760.     /|  { noaccess put /|  //undef_proc_warning exec } executeonly bdef
  761.     /NP { noaccess put /NP //undef_proc_warning exec } executeonly bdef
  762.   currentdict end readonly def
  763.  
  764.   /eexec {
  765.     % Assume the font dictionary is directly below the file on the stack
  766.     count 0 gt { /topFontDict 2 index cvlit store } if
  767.     //eexec_pdf_param_dict /eexecDecode filter
  768.  
  769.     //missing-type1-procs begin
  770.     /userdict .systemvar begin
  771.     //systemdict begin
  772.     readtype1dictcopy begin cvx stopped
  773.  
  774.     { currentdict end //missing-type1-procs eq { exit } if } loop
  775.     { stop } if
  776.   } bdef
  777.  
  778.   /readonly-op-dict <<
  779.     /stringtype 0
  780.     /arraytype 0
  781.     /packedarraytype 0
  782.     /dicttype 0
  783.   >> readonly def
  784.  
  785.   /readonly { % bug 689617
  786.     dup type //readonly-op-dict exch known {
  787.     readonly
  788.   } {
  789.     (   **** Warning: Type 1 font applies operator readonly to a wrong type.\n)
  790.     pdfformaterror
  791.   } ifelse } .bind def
  792.  
  793.   currentdict dup dup
  794.   /undef_proc_warning undef
  795.   /missing-type1-procs undef
  796.   /readonly-op-dict undef
  797.  
  798. end readonly def
  799.  
  800. currentdict /eexec_pdf_param_dict .undef
  801.  
  802. /readtype1 {        % <font-resource> <stream-dict> readtype1 <font>
  803.    1 index exch                       % res res stream
  804.    PDFfile fileposition 3 1 roll      % res pos res stream
  805.    dup /PFB known exch                % res pos res pfb? stream
  806.    true resolvestream                 % res pos res pfb? file
  807.    exch {
  808.      //false /PFBDecode filter
  809.    } if
  810.         % Some buggy embedded fonts leave extra junk on the stack,
  811.         % so we have to make a closure that records the stack depth
  812.         % in a fail-safe way. This code also removes the mark when
  813.                 % the implied cleartomark is not executed, i.e. Length3 == 0.
  814.                 % Also restore dictstack depth.
  815.                 % 
  816.    //systemdict begin
  817.    //readtype1dict dup length 3 add dict copy begin
  818.    1 index /BaseFont oget /savedFontName exch def
  819.    /topFontDict null def
  820.    /readtype1dictcopy currentdict def
  821.     { cvx exec } aload pop count 2 sub 3 packedarray cvx exec
  822.     % clean up the dictstack
  823.     { currentdict /topFontDict known not { end } { exit } ifelse } loop
  824.    count exch sub { pop } repeat
  825.    PDFfile 3 -1 roll setfileposition
  826.    pop pop
  827.    currentdict end end /topFontDict get
  828.  } bdef
  829.  
  830. % ---------------- Type 3 fonts ---------------- %
  831.  
  832. /buildType3 {        % <Type3-font-resource> buildType3 <font>
  833.   8 dict begin
  834.     /FontType 3 def
  835.         % If the font does not contain a Resources entry, then we use
  836.         % the resources from our current context.  Page 391 of the PDF
  837.         % 1.6 spec says that the Resources dict is optional and if not
  838.         % present then we should use the Resources for the page.
  839.         % However we have a test file (687989) which uses a Type3 font
  840.         % inside a form XObject and the desired Resources are in the
  841.         % XObject dict and not in the Page dict.  So we are going to
  842.         % the parent object to find resources instead of only going to
  843.         % the page dict when a font does not specify its required
  844.         % resources.
  845.     /Resources 1 index /Resources knownoget {
  846.        oforce
  847.     } {
  848.        LocalResources
  849.     } ifelse def
  850.     /FontBBox 1 index /FontBBox get cvx def
  851.     /FontMatrix 1 index /FontMatrix oget def
  852.     /CharProcs 1 index /CharProcs oget def
  853.     1 index /Widths knownoget {
  854.       /Widths exch def
  855.       /FirstChar 1 index /FirstChar oget def
  856.       /LastChar 1 index /LastChar oget def
  857.     } if
  858.     /FontName 1 index /Name knownoget not { /PDFType3Untitled } if def
  859.     /Encoding .notdefEncoding 2 index getencoding def
  860.         % We have to define BuildChar rather than BuildGlyph:
  861.         % there is no PDF equivalent of glyphshow, and we need
  862.         % the character code to access the Widths.
  863.     /BuildChar {
  864.         % Stack: font charcode
  865.       1 index begin 3 dict begin
  866.       /Font 3 -1 roll def /CharCode 1 index def
  867.       Encoding exch get CharProcs exch knownoget {
  868.         { //false resolvestream
  869.         % Stack: filepos stream
  870.         % Don't let setgcolor set the color inside the BuildGlyph
  871.         % procedure, because this causes an /undefined error.
  872.           q //null /FillColor gput //null /StrokeColor gput
  873.           Font /Resources get exch pdfopdict .pdfruncontext
  874.           Q
  875.         } PDFfile fileposition 2 .execn % Keep pdfcount valid.
  876.         PDFfile exch setfileposition
  877.       } {
  878.         % PDF Type 3 fonts don't use .notdef
  879.         % d1 implementation adjusts the width as needed
  880.         0 0 0 0 0 0
  881.         pdfopdict /d1 get exec
  882.       } ifelse
  883.       end end
  884.     } bdef
  885.     dup currentdict Encoding .processToUnicode
  886.     currentdict end .completefont exch pop
  887. } bdef
  888. /.adjustcharwidth {    % <wx> <wy> .adjustcharwidth <wx'> <wy'>
  889.   % Enforce the metrics, in glyph space, to the values found in the PDF Font object
  890.   % - force wy == 0 (assumed, and not stored in the PDF font)
  891.   %   Even though PDF1.3-1.7 specifications state that this must be 0,
  892.   %   Distiller sometimes creates Type3 fonts with non-zero wy. We set
  893.   %   it to 0 since this is apparently what Acrobat Reader 4 and 5 do.
  894.   %   PDF1.2 does not mention this restriction, it only says
  895.   %   "see setcharwidth/ setcachedevice in the PostScript Reference".
  896.   % - get wx from the Widths array (do nothing if not present)
  897.   pop 0
  898.   /Widths where {
  899.     begin
  900.     CharCode FirstChar ge CharCode LastChar le and {
  901.       exch pop Widths CharCode FirstChar sub get exch
  902.     } if end
  903.   } if
  904. } bdef
  905.  
  906. % ---------------- TrueType fonts ---------------- %
  907.  
  908. /TTfonts mark
  909.   /Arial /Helvetica
  910.   /Arial,Italic /Helvetica-Oblique
  911.   /Arial,Bold /Helvetica-Bold
  912.   /Arial,BoldItalic /Helvetica-BoldOblique
  913.   /CourierNew /Courier
  914.   /CourierNew,Bold /Courier-Bold
  915.   /TimesNewRoman /Times-Roman
  916.   /TimesNewRoman,Italic /Times-Italic
  917.   /TimesNewRoman,Bold /Times-Bold
  918.   /TimesNewRoman,BoldItalic /Times-BoldItalic
  919. .dicttomark readonly def
  920.  
  921. /buildTrueType {    % <TrueType-font-resource> buildTrueType <font>
  922.   dup /BaseFont oget
  923.   dup /Font resourcestatus dup { exch pop exch pop } if not
  924.   TTfonts 2 index known and {
  925.     dup TTfonts exch get
  926.     QUIET not {
  927.       (Substituting font ) print dup =only
  928.       ( for ) print 1 index =only (.) = flush
  929.     } if
  930.     exch 3 1 roll pdffindfont
  931.     true .copyfontdict
  932.     2 copy exch /FontName exch put
  933.     exch pop .completefont
  934.   } {
  935.     pdffindfont
  936.   } ifelse
  937. } bdef
  938.  
  939. % Read an embedded TrueType font.
  940. /readtruetype {        % <font-resource> <stream-dict> readtruetype <font>
  941.   1 index exch
  942.   PDFfile fileposition 3 1 roll
  943.   true resolvestream readfontfilter
  944.         % Stack: filepos fontres stream
  945.   1 index /Subtype get /CIDFontType2 eq {
  946.     .loadttcidfont
  947.         % Stack: filepos fontres cidfont
  948.   } {
  949.                                   % filepos fontres stream
  950.     1 index /FontDescriptor oget          % filepos fontres stream fd   
  951.     /Flags get 4 and 0 ne                 % filepos fontres stream is_symbolic
  952.     dup { //null } { StandardEncoding } ifelse        
  953.     3 index /Encoding known {
  954.       3 index getencoding
  955.     } if                                  % filepos fontres stream is_symbolic Encoding
  956.     dup 4 index exch                      % filepos fontres stream is_symbolic Encoding fontres Encoding
  957.     /prebuilt_encoding exch put           % filepos fontres stream is_symbolic Encoding
  958.     .loadpdfttfont
  959.   } ifelse
  960.   exch pop
  961.   PDFfile 3 -1 roll setfileposition
  962.         % Ignore both the Encoding and the Widths.
  963.   exch pop
  964. } bdef
  965.  
  966. % ---------------- Type 0 fonts ---------------- %
  967.  
  968. % Predefine the known CMaps, but only create them on demand.
  969. /knownCMaps mark
  970.   /Identity-H { /Identity-H 0 makeIdentityCMap }
  971.   /Identity-V { /Identity-V 1 makeIdentityCMap }
  972. .dicttomark def
  973.  
  974. /makeIdentityCMap {        % <cmapname> <wmode> .makeIdentityCMap -
  975.   .currentglobal true .setglobal 3 1 roll
  976.   /CIDInit /ProcSet findresource begin
  977.   12 dict begin
  978.     begincmap
  979.     /WMode exch def
  980.     /CMapName exch def
  981.     /CIDSystemInfo 3 dict dup begin
  982.       /Registry (Adobe) def
  983.       /Ordering (Identity) def
  984.       /Supplement 0 def
  985.     end def
  986.     %/CMapName (see above)
  987.     /CMapVersion 1 def
  988.     /CMapType 1 def
  989.     %WMode (see above)
  990.     % The PDF documentation says that these CMaps map CIDs
  991.     % "1 to 65,536".  This is a misprint for 0 to 65,535.
  992.     1 begincodespacerange
  993.     % <0001> <00ff>  <0100> <ffff>
  994.       <0000> <ffff>
  995.     endcodespacerange
  996.     1 begincidrange
  997.     % <0001> <00ff> 1   <0100> <ffff> 256
  998.       <0000> <ffff> 0
  999.     endcidrange
  1000.     endcmap
  1001.     CMapName currentdict /CMap defineresource
  1002.     knownCMaps CMapName 2 index put
  1003.   end        % CMap
  1004.   end        % CIDInit ProcSet
  1005.   exch .setglobal
  1006. } bdef
  1007.  
  1008. /buildType0 {        % <Type0-font-resource> buildType0 <font>
  1009.   dup /BaseFont get    % FontName
  1010.   1 index /Encoding oget
  1011.   dup type /nametype eq {
  1012.     dup /CMap resourcestatus {
  1013.     pop pop /CMap findresource
  1014.     } {
  1015.     knownCMaps 1 index .knownget
  1016.       { exch pop exec } { /undefined signalerror } ifelse
  1017.     } ifelse
  1018.   } {
  1019.     PDFfile fileposition exch
  1020.     dup /CMapName get exch true resolvestream cvx exec
  1021.     /CMap findresource
  1022.     exch PDFfile exch setfileposition
  1023.   } ifelse        % CMap
  1024.   [
  1025.     3 index /DescendantFonts oget { exec resourcefont } forall
  1026.   ]            % subfonts
  1027.   .composefontdict  % composefont must insert FontInfo dictionary - see gs_cmap.ps .
  1028.             % Stack: fontres name font
  1029.   3 copy exch pop null .processToUnicode
  1030.   exch pop .completefont % Stack: fontres font
  1031.   1 index /FontMatrix knownoget {
  1032.     dup aload pop true {0 0 1 0 0 1} {3 -1 roll eq and} forall {
  1033.       1 index exch makefont exch /FontName get exch 
  1034.       exch pop .completefont
  1035.     } {
  1036.       pop
  1037.     } ifelse
  1038.   } if exch pop
  1039. } bdef
  1040.  
  1041. % ---------------- CIDFontType0/2 fonts ---------------- %
  1042.  
  1043. % Insert metrics into a CIDFont, by saving the PDF W, W2, DW, and DW2
  1044. % arrays and using a (currently very inefficient) CDevProc.
  1045. % For detail, refer "PDF Reference" 2nd ed., p314 "5.6.3 CIDFonts".
  1046. % It notes default DW is 0, but Acrobat Reader uses 1000 as default.
  1047. % If DW is 0, currentpoint does not move by default in rendering text
  1048. % horizontally, the result is unreadable. You can check it by Acrobat.
  1049.  
  1050. /.pdfDefaultDW  1000 def
  1051. /.pdfDefaultDW2 [ 880 -1000 ] def
  1052.  
  1053. /addCIDmetrics {    % <CIDFont-resource> <CIDFont> addCIDmetrics <fontdict>
  1054.   dup length 5 add dict .copydict
  1055.   dup /FID undef
  1056.   dup /UniqueID undef
  1057.   dup /XUID undef
  1058.     % Insert the widths into the font.
  1059.  
  1060.         % Stack: pdfresource newfont
  1061.  
  1062.   1 index /DW knownoget {
  1063.     1 index /DW 3 -1 roll put
  1064.   } {
  1065.     dup /DW .pdfDefaultDW put
  1066.   } ifelse
  1067.  
  1068.   1 index /W knownoget {
  1069.     //false 1 index { xcheck or } forall {
  1070.       oforce_array
  1071.     } if
  1072.     dup 2 index /W 3 -1 roll put
  1073.     .pdfMakeInternalW 1 index /.internalW 3 -1 roll put
  1074.   } if
  1075.  
  1076.   1 index /DW2 knownoget {
  1077.     1 index /DW2 3 -1 roll put
  1078.   } {
  1079.     dup /DW2 .pdfDefaultDW2 put
  1080.   } ifelse
  1081.  
  1082.   1 index /W2 knownoget {
  1083.     //false 1 index { xcheck or } forall {
  1084.       oforce_array
  1085.     } if
  1086.     dup 2 index /W2 3 -1 roll put
  1087.     .pdfMakeInternalW2 1 index /.internalW2 3 -1 roll put
  1088.   } if
  1089.  
  1090.   dup /CDevProc 1 index /CIDWProc load /exec load 3 packedarray cvx put
  1091.   exch pop
  1092. } bdef
  1093.  
  1094. /.pdfMakeInternalMTXArray { % <mtx_array> <item_size> .pdfConvertInternalW <mtx_array'>
  1095.  
  1096.   % convert /W or /W2 to internal expression
  1097.   %
  1098.   %   mtx_array: original /W or /W2 array
  1099.   %   item_size: number of metrics values per CID
  1100.   %
  1101.   %   for detail of the metrics list format in PDF,
  1102.   %   refer PDF Ref. p.317 "Glyph Metrics in CIDFonts".
  1103.   % 
  1104.   %   format of single entry in internal expression
  1105.   %
  1106.   %     [
  1107.   %       [cid_begin cid_end]
  1108.   %       value_is_varied (bool)
  1109.   %       [ [values for cid_begin...]
  1110.   %         [values for cid_begin + 1]
  1111.   %         ... ]
  1112.   %     ]
  1113.   %
  1114.  
  1115.   7 dict
  1116.   begin
  1117.     /itemSize exch def
  1118.     /M exch def            % original /W or /W2
  1119.     /Msize M length def
  1120.     /Mi { M i get } def        % W[i]
  1121.     /Mi1 { M i 1 add get } def    % W[i + 1]
  1122.     /putMTXEntry <<
  1123.       /arraytype   {
  1124.          [
  1125.            [Mi Mi Mi1 length itemSize idiv add 1 sub]
  1126.            true
  1127.            [
  1128.              0 itemSize Mi1 length 1 sub {
  1129.                [ exch 1 1 index itemSize add 1 sub { Mi1 exch get } for ]
  1130.              } for
  1131.            ]
  1132.          ]
  1133.          /i i 2 add def
  1134.       }
  1135.       /integertype {
  1136.          [
  1137.            [Mi Mi1]
  1138.            false
  1139.            [[ i 2 add 1 i 1 add itemSize add { M exch get } for ]]
  1140.          ]
  1141.          /i i 3 add def
  1142.       }
  1143.     >> def
  1144.  
  1145.     /i 0 def
  1146.  
  1147.     [ { putMTXEntry Mi1 type get exec i Msize ge { exit } if } loop ]
  1148.   end
  1149. } def
  1150.  
  1151. /.pdfMakeInternalW  { dup length 0 gt { 1 .pdfMakeInternalMTXArray } if } def
  1152. /.pdfMakeInternalW2 { dup length 0 gt { 3 .pdfMakeInternalMTXArray } if } def
  1153.  
  1154. /.pdfGetMTXByCID { % <internalMTXArray> <cid>
  1155.                    %     .pdfGetMTXByCID
  1156.                    %         { <MTXEntry> true | false }
  1157.  
  1158.   % get values for given CID from internal format of /W or /W2
  1159.  
  1160.   exch
  1161.   {
  1162.     { 
  1163.       dup 0 get {} forall      % Stack: <cid> <entry> <cid_0> <cid_1>
  1164.       3 index lt { pop pop false exit } if
  1165.       2 index exch sub dup 0 lt { pop pop false exit } if
  1166.       1 index 1 get not { pop 0 } if
  1167.       exch 2 get exch get true exit
  1168.     } loop
  1169.     { exit } if
  1170.   } forall
  1171.   dup type /arraytype eq { exch pop true } { pop false } ifelse
  1172. } def
  1173.  
  1174.  
  1175. % Apply the [D]W[2] metrics to a character before displaying.
  1176. /CIDWProc {        % <w0x> <w0y> <llx> <lly> <urx> <ury>
  1177.             %   <w1x> <w1y> <vx> <vy> <cid> <font> CIDWproc
  1178.             %   <w0x'> ... <vy'>
  1179.   begin % push <font> to currentdict
  1180.     % <w1x> <w1y> <vx> <vy> won't be used and replaced, discard now
  1181.     5 1 roll pop pop pop pop
  1182.  
  1183.     {
  1184.       currentdict /DW .knownget not {   % no DW
  1185.         .pdfDefaultDW exit              % replace <w0x> by defaultDW
  1186.       } if
  1187.  
  1188.       currentdict /.internalW .knownget not {    % no W
  1189.         exit                            % use already-stacked DW
  1190.       } if
  1191.  
  1192.       dup length 0 eq {                 % W is null array
  1193.         pop                             % discard unusable W
  1194.         exit                            % use already-stacked DW
  1195.       } if
  1196.  
  1197.       % W is finite array, try to get W_cid
  1198.       2 index .pdfGetMTXByCID {           % got W, discard DW
  1199.         exch pop {} forall
  1200.         exit
  1201.       } if
  1202.  
  1203.       exit
  1204.     } loop
  1205.  
  1206.     FontType 11 eq {
  1207.       1000 div                  % <w0x'> (normalized W)
  1208.     } if
  1209.     0                           % <w0y'>
  1210.  
  1211.     % Stack: <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <w0x'> <w0y'>
  1212.     9 -2 roll pop pop           % discard <w0x> <w0y>
  1213.     7  2 roll                   % put <w0x'> <w0y'>
  1214.  
  1215.     % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <cid>
  1216.     0                           % <w1x'>
  1217.     exch                        % put <w1x'>
  1218.  
  1219.     % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <cid>
  1220.     {
  1221.       currentdict /DW2 .knownget not {  % no DW2, use defaultDW2
  1222.         .pdfDefaultDW2 exit
  1223.       } if
  1224.  
  1225.       currentdict /.internalW2 .knownget not {   % has DW2, no W2
  1226.         exit                            % use already-stacked DW2
  1227.       } if
  1228.  
  1229.       dup length 0 eq {                 % W2 is null array
  1230.         pop                             % discard unusable W2
  1231.         exit                            % use already-stacked DW2
  1232.       } if
  1233.  
  1234.       2 index .pdfGetMTXByCID {        % got W2_cid, discard DW2
  1235.         exch pop
  1236.         exit
  1237.       } if
  1238.  
  1239.       % could not get W2_cid
  1240.       exit
  1241.  
  1242.     } loop
  1243.  
  1244.     exch pop                            % discard <cid>
  1245.  
  1246.     % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> { [<vy'> <w1y'>] | [<w1y'> <vx'> <vy'>] }
  1247.     dup length 2 eq {                   % this is DW2
  1248.       FontType 11 eq {{1000 div}} {{}} ifelse forall exch
  1249.       8 index 2 div                     % <vx'> = <w0x'> / 2
  1250.       exch
  1251.     }{                                  % assume W2
  1252.       FontType 11 eq {{1000 div}} {{}} ifelse forall
  1253.     } ifelse
  1254.   end                                   % recover currentdict
  1255.  
  1256. } def
  1257.  
  1258. % <string> <match> tailmatch ==> <pre> true
  1259. %                            ==> <string> false
  1260. /tailmatch {
  1261.   2 copy length 1 index length .min
  1262.   dup 2 index length exch sub exch getinterval
  1263.   1 index eq {
  1264.     length 1 index length exch sub
  1265.     0 exch getinterval true
  1266.   } {
  1267.     pop false
  1268.   } ifelse
  1269. } bind def
  1270.  
  1271. /makeboldfont {
  1272.   16 dict begin
  1273.     /strokewidth exch def
  1274.     /basecidfont exch def
  1275.     /FontMatrix [ 1 0 0 1 0 0 ] def
  1276.  
  1277.     /CIDFontName /.boldfont def
  1278.     /CIDFontType 1 def
  1279.  
  1280.     /basefont-H /.basefont-H /Identity-H [ basecidfont ] composefont def
  1281.     /basefont-V /.basefont-V /Identity-V [ basecidfont ] composefont def
  1282.  
  1283.     /CIDSystemInfo dup basecidfont exch get def
  1284.     /FontBBox [ basecidfont /FontBBox get cvx exec
  1285.       4 2 roll basecidfont /FontMatrix get transform
  1286.       4 2 roll basecidfont /FontMatrix get transform
  1287.     ] def
  1288.  
  1289.     /tmpstr 2 string def
  1290.     /BuildGlyph {
  1291.       gsave
  1292.       exch begin
  1293.         dup 256 idiv tmpstr exch 0 exch put
  1294.         256 mod tmpstr exch 1 exch put
  1295.         rootfont /WMode known { rootfont /WMode get 1 eq } { false } ifelse
  1296.         { basefont-V } { basefont-H } ifelse setfont
  1297.         strokewidth setlinewidth
  1298.         1 setlinejoin
  1299.         newpath
  1300.         0 0 moveto tmpstr false charpath stroke
  1301.         0 0 moveto tmpstr show
  1302.         currentpoint setcharwidth
  1303.       end
  1304.       grestore
  1305.     } bind def
  1306.  
  1307.    currentdict
  1308.   end
  1309.   dup /CIDFontName get exch /CIDFont defineresource
  1310. } bind def
  1311.  
  1312. % <CIDFont-resource> <CIDFontName> findCIDFont <CIDFont-resource> <font>
  1313. %   CIDFont-resource is not modified.
  1314. /findCIDFont {
  1315.   {
  1316.     dup /CIDFont resourcestatus {
  1317.       pop pop /CIDFont findresource
  1318.       exit
  1319.     } if
  1320.     .remove_font_name_prefix
  1321.     dup dup length string cvs
  1322.     (,Bold) tailmatch {
  1323.       exch pop
  1324.       cvn findCIDFont 0.03 makeboldfont
  1325.       exit
  1326.     } if
  1327.     (,Italic) tailmatch {
  1328.       exch pop
  1329.       cvn findCIDFont
  1330.       [ 1 0 0.3 1 0 0 ] makefont
  1331.       exit
  1332.     } if
  1333.     (,BoldItalic) tailmatch {
  1334.       exch pop
  1335.       cvn findCIDFont 0.03 makeboldfont
  1336.       [ 1 0 0.3 1 0 0 ] makefont
  1337.       exit
  1338.     } if
  1339.     QUIET not {
  1340.       (Can't find CID font ") print dup =string cvs print (".) =  
  1341.     } if
  1342.     pop
  1343.  
  1344.     1 index /CIDSystemInfo oget begin Registry (-) Ordering end
  1345.     concatstrings concatstrings
  1346.     cvn
  1347.     QUIET not {
  1348.       (Substituting CID font resource ) print dup ==only
  1349.       ( for ) print 1 index ==only (.\n) print
  1350.     } if
  1351.     exch pop
  1352.     dup /CIDFont resourcestatus {
  1353.       pop pop /CIDFont findresource exit 
  1354.     } if
  1355.     QUIET not {
  1356.       (The substitute CID font ") print dup =string cvs print 
  1357.       (" is not provided either. Will exit with error.) =  
  1358.     } if
  1359.     /findresource cvx /undefined signalerror
  1360.   } loop
  1361. } bdef
  1362.  
  1363. /buildCIDType0 {    % <CIDFontType0-font-resource> buildCIDType0 <font>
  1364.   dup /BaseFont get findCIDFont exch pop
  1365. } bdef
  1366.  
  1367. /buildCIDType2 {    % <CIDFontType2-font-resource> buildCIDType2 <font>
  1368.   dup /BaseFont get findCIDFont exch pop
  1369. } bdef
  1370.  
  1371. /processCIDToGIDMap { % <fontres> <cidfont> processCIDToGIDMap <fontres> <cidfont>
  1372.   1 index /CIDToGIDMap knownoget {
  1373.     PDFfile fileposition 4 1 roll
  1374.     dup /Identity eq {
  1375.       pop
  1376.     } {
  1377.       true resolvestream
  1378.         % Stack: filepos fontres font mapstream
  1379.     % Can't know the length of the decompressed stream, so allocate a big buffer...
  1380.       dup 65534 string readstring {
  1381.        % Length exceeded max string size, use an array of two strings
  1382.        1 index 65534 string readstring pop   % maybe a null string - not important.
  1383.           2 array astore
  1384.                   % Stack: filepos fontres font mapstream array 
  1385.           dup 1 get length 65534 add
  1386.       } {
  1387.         dup length
  1388.       } ifelse
  1389.       2 idiv
  1390.         % Stack: filepos fontres font mapstream array/string CIDCount
  1391.       3 index exch /CIDCount exch put
  1392.       exch closefile exch
  1393.       dup /CIDMap 4 -1 roll put
  1394.     } ifelse
  1395.     3 2 roll PDFfile exch setfileposition
  1396.   } if
  1397. } bdef
  1398.  
  1399. % Adjust a CIDFontType0 DW[2] in the font resource.
  1400. /adjustCIDType0 {        % <font-resource> <font> adjustfont <font'>
  1401.   addCIDmetrics
  1402.   dup /CIDFontName get exch /CIDFont defineresource
  1403. } bind def
  1404.  
  1405. % Adjust a CIDFontType2 DW[2] and CIDToGIDMap in the font resource.
  1406. /adjustCIDType2 {        % <font-resource> <font> adjustfont <font'>
  1407.   addCIDmetrics
  1408.   dup /CIDFontType get 2 eq {   % OpenType CFF font converts to CIDFontType 0
  1409.     processCIDToGIDMap          %  that ignores CIDMap.
  1410.   } if
  1411.   dup /CIDFontName get exch /CIDFont defineresource
  1412. } bind def
  1413.  
  1414. % ---------------- Other embedded fonts ---------------- %
  1415.  
  1416. /fontloadprocs mark
  1417.   /Type1C /readType1C cvx
  1418.   /CIDFontType0C /readCIDFontType0C cvx
  1419. .dicttomark readonly def
  1420.  
  1421. % Read an embedded compressed font.
  1422. /readType1C {        % <font-resource> <stream-dict> readType1C <font>
  1423.   1 index exch
  1424.   PDFfile fileposition 3 1 roll
  1425.   dup true resolvestream dup readfontfilter
  1426.         % Stack: pos resource streamdict stream filter
  1427.   3 index /FontDescriptor oget /FontName oget
  1428.   1 index 
  1429.   /FontSetInit /ProcSet findresource begin //true //false ReadData
  1430.   { exch pop exit } forall
  1431.   7 1 roll
  1432.   closefile closefile pop
  1433.   PDFfile 3 -1 roll setfileposition
  1434.   pop pop
  1435. } bdef
  1436.  
  1437. % Read an embedded CFF CIDFont.
  1438. /readCIDFontType0C {  % <font-resource> <stream-dict> readCIDFontType0C <font>
  1439.   PDFfile fileposition 3 1 roll
  1440.   dup true resolvestream dup readfontfilter
  1441.         % Stack: pos resource streamdict stream filter
  1442.   3 index /FontDescriptor oget /FontName oget
  1443.   1 index 
  1444.   /FontSetInit /ProcSet findresource begin //true //false ReadData pop
  1445.   closefile closefile pop
  1446.   PDFfile 3 -1 roll setfileposition
  1447.         % Some broken Adobe software produces PDF files in which
  1448.         % the FontName of the CFF font and the FontName in the
  1449.         % FontDescriptor don't match the BaseFont in the font.
  1450.         % Use the FontName, rather than the BaseFont, here.
  1451.   dup /FontDescriptor oget /FontName oget /CIDFont findresource
  1452.   addCIDmetrics dup /CIDFontName get exch /CIDFont defineresource
  1453. } bdef
  1454.  
  1455. % Read an embedded OpenType font.
  1456. /readOTTOfont {        % <font-resource> <stream-dict> readOTTOfont <font>
  1457.   1 index exch                    % res res strdict
  1458.   PDFfile fileposition 3 1 roll   % res pos res strdict
  1459.   dup //true resolvestream        % res pos res strdict stream
  1460.   dup readfontfilter              % res pos res strdict stream filter
  1461.   3 index /FontDescriptor oget
  1462.   /FontName oget                  % res pos res strdict stream filter /name
  1463.   1 index .init_otto_font_file    % res pos res strdict stream filter /name filter'
  1464.   //true
  1465.   6 index /CIDSystemInfo known    % res pos res strdict stream filter /name filter' bool bool
  1466.   ReadData                        % res pos res strdict stream filter fontset
  1467.   { exch pop exit } forall        % res pos res strdict stream filter font
  1468.   dup /FontType get 9 eq  {
  1469.     % OpenType may contain simple CFF font, which is accesed as a CIDFont by PDF.
  1470.     % The font is converted to Type 9 CIDFont resource, which ignores CIDMap attribute.
  1471.     % The following code just shuffles GlyphDirectory to the same effect.
  1472.     4 index /CIDToGIDMap knownoget {
  1473.       dup type /dicttype eq {
  1474.         1 index /GlyphDirectory get exch       % res pos res strdict stream filter font dir c2g
  1475.         //true resolvestream                   % res pos res strdict stream filter font dir c2g_file
  1476.         256 dict begin
  1477.         0 2 index 0 get def  % copy .notdef
  1478.         0 1 16#7fffffff {
  1479.           1 index read not { pop exit } if     % res pos res strdict stream filter font dir c2g_file cid hi
  1480.           256 mul                              % res pos res strdict stream filter font dir c2g_file cid hi
  1481.           2 index read not { pop pop exit } if % res pos res strdict stream filter font dir c2g_file cid hi lo
  1482.           add                                  % res pos res strdict stream filter font dir c2g_file cid gid
  1483.           dup 0 ne {
  1484.             dup 4 index length lt {
  1485.               3 index exch get                 % res pos res strdict stream filter font dir c2g_file cid charstr
  1486.               def                              % res pos res strdict stream filter font dir c2g_file
  1487.             } {
  1488.               pop pop
  1489.             } ifelse
  1490.           } {
  1491.             pop pop
  1492.           } ifelse
  1493.         } for
  1494.         closefile pop                          % res pos res strdict stream filter font
  1495.         dup length dict copy                   % res pos res strdict stream filter font'
  1496.         dup /GlyphDirectory currentdict put    % res pos res strdict stream filter font'
  1497.         end
  1498.         dup /GlyphDirectory get 0 exch {
  1499.           pop .max
  1500.         } forall
  1501.         1 index exch /CIDCount exch 1 add put
  1502.       } {
  1503.       pop
  1504.       } ifelse
  1505.     } if
  1506.   } if
  1507.   7 1 roll                        % font res pos res strdict stream filter
  1508.   closefile closefile pop pop     % font res pos
  1509.   PDFfile exch setfileposition    % font res
  1510.   pop                             % font
  1511. } bdef
  1512.  
  1513. % ---------------- Font lookup ---------------- %
  1514.  
  1515. % Some PDF files mis-identify font type of the embedded font streams or
  1516. % include raw PFB font streams. Length1, Length2, Length3 may be wrong or
  1517. % missing. Adobe Acrobat corrects these errors transparently to the user.
  1518. %
  1519. % We ignore the font type keys and recognize the font type by the 1st 4 bytes
  1520. % of the font stream. The PFB stream is recognized by the 1st 2 bytes.
  1521.  
  1522. /fonttypeprocs mark        % <font-resource> -proc- <font>
  1523.   /Type0 //buildType0
  1524.   /Type1 //buildType1
  1525.   /MMType1 //buildType1
  1526.   /Type3 //buildType3
  1527.   /TrueType //buildTrueType
  1528.   /CIDFontType0 //buildCIDType0
  1529.   /CIDFontType2 //buildCIDType2
  1530. .dicttomark readonly def
  1531.  
  1532. /adjustfonttypes mark
  1533.   /Type1 //adjustfont
  1534.   /MMType1 //adjustfont
  1535.   /TrueType //adjustfont
  1536.   /CIDFontType0 //adjustCIDType0
  1537.   /CIDFontType2 //adjustCIDType2
  1538. .dicttomark readonly def
  1539.  
  1540. % Bind a proc and define n names
  1541. % /name ... /name {proc} n bndef -
  1542. /bndef
  1543.   { exch bind exch
  1544.     { dup 3 1 roll def } repeat
  1545.     pop
  1546.   } bdef
  1547.  
  1548. % Prototype for all procedures: <res> <desc> <stream> foo <font>
  1549. /font_tag_dict 13 dict begin
  1550.  
  1551.   % When the font stream is absent or cannot be read we load the font by the name.
  1552.   /no_stream 
  1553.     { pop pop 
  1554.       dup /Subtype get  % res res /subtype
  1555.       dup / eq {
  1556.         (   **** Warning: Font missing required Subtype, /Type1 assumed.\n)
  1557.     pdfformaterror
  1558.         pop /Type1
  1559.       } if
  1560.       //fonttypeprocs exch get exec 
  1561.     } bdef
  1562.  
  1563.   /bad_stream 
  1564.     { (   **** Warning: Error reading font stream, loading font by the name\n)
  1565.       pdfformaterror
  1566.       //no_stream exec
  1567.     } bdef
  1568.  
  1569.   <8001>          % PFB 
  1570.     { dup /PFB //true put
  1571.       exch pop readtype1
  1572.     } bdef
  1573.  
  1574.   (%!PS) (%!Fo)   % Type1
  1575.     { exch pop readtype1
  1576.     } 2 bndef
  1577.  
  1578.   <01000401> <01000402> <01000403> <01000404> % Type 1C
  1579.   <01000C02>
  1580.     { exch pop
  1581.       dup /Subtype get
  1582.       fontloadprocs exch get exec
  1583.     } 5 bndef 
  1584.  
  1585.   <00010000> (true) (typ1) (ttcf)  % TrueType OpenType
  1586.     { exch pop readtruetype
  1587.     } 4 bndef
  1588.  
  1589.   (OTTO)
  1590.     { exch pop
  1591.       readOTTOfont
  1592.     } bdef
  1593.  
  1594.  
  1595. currentdict end readonly def
  1596. currentdict /bndef undef
  1597.  
  1598. /resourcefont                   % <font-resource> resourcefont <font>
  1599. { dup /PSFont .knownget dup {
  1600.     pop /FID knownoget dup { pop type /fonttype eq } if
  1601.   } if {
  1602.     /PSFont get 
  1603.   } {
  1604.     dup dup /FontDescriptor knownoget {
  1605.                                           % font-res font-res font-desc
  1606.       % The same font descriptor can be reused in a CID and non-CID contexts.
  1607.       % Store CID and non-CID fonts under different keys. Bug 689301
  1608.       1 index /Subtype knownoget dup {
  1609.         pop dup /CIDFontType0 eq exch /CIDFontType2 eq or
  1610.       } if { /CIDFontObject } { /FontObject } ifelse
  1611.                                           % font-res font-res font-desc /key
  1612.       2 copy .knownget {
  1613.         4 1 roll pop pop pop              % font-res obj
  1614.       } {    
  1615.         4 1 roll                          % /key font-res font-res font-desc
  1616.  
  1617.         dup /FontFile knownoget not {
  1618.           dup /FontFile2 knownoget not {
  1619.             dup /FontFile3 knownoget not {
  1620.               //null
  1621.             } if
  1622.           } if
  1623.         } if
  1624.                                           % /key res res desc stream
  1625.         dup //null ne {
  1626.           PDFfile fileposition 
  1627.           1 index //true resolvestream dup
  1628.           4 string readstring pop
  1629.       exch closefile
  1630.           PDFfile 3 -1 roll setfileposition
  1631.           dup length 4 lt { pop /bad_stream } if
  1632.         } {
  1633.           /no_stream
  1634.     } ifelse
  1635.                                           % /key res res desc stream tag          
  1636.  
  1637.         //font_tag_dict 1 index known not {
  1638.           dup 0 2 getinterval <8001> eq {
  1639.             0 2 getinterval               % /key res res desc stream pfb_tag
  1640.       } { 
  1641.             (12345678>\n) dup /ASCIIHexEncode filter dup 4 -1 roll writestring closefile
  1642.             (   **** Warning: unrecognized font file starts with <) exch concatstrings
  1643.         pdfformaterror
  1644.         /no_stream                    % /key res res desc stream unknown_tag
  1645.           } ifelse    
  1646.     } if        
  1647.           
  1648.     //font_tag_dict exch get exec
  1649.    
  1650.         1 index /FontDescriptor oget      % /key res font desc
  1651.         4 -1 roll 2 index                 % res font desc /key font
  1652.         put  % Save pointer to the font.
  1653.       } ifelse
  1654.     } {
  1655.       dup /Subtype get
  1656.       dup / eq {
  1657.         (   **** Warning: Font missing required Subtype, /Type1 assumed.\n)
  1658.         pdfformaterror
  1659.         pop /Type1
  1660.       } if 
  1661.       //fonttypeprocs exch get exec
  1662.     } ifelse
  1663.         % Stack: font-res font
  1664.     1 index exch
  1665.     1 index /Subtype get
  1666.     //adjustfonttypes exch .knownget { exec } { exch pop } ifelse
  1667.     dup 3 1 roll /PSFont exch put
  1668.   } ifelse
  1669.   dup checkGlyphNames2Unicode
  1670. } bdef
  1671.  
  1672. currentdict /font_tag_dict .undef
  1673. currentdict /fonttypeprocs .undef
  1674. currentdict /adjustfonttypes .undef
  1675.  
  1676. drawopdict begin
  1677.   /d0 {
  1678.     .adjustcharwidth setcharwidth
  1679.   } bdef
  1680.   /d1 {
  1681.     2 copy                           % ... llx lly urx ury | urx ury 
  1682.     0 ne exch 0 ne                   % ... llx lly urx ury | ury!=0 urx!=0
  1683.     3 index 6 index eq and           % ... llx lly urx ury | ury!=0 (urx!=0 && llx==urx)
  1684.     exch 2 index 5 index eq and or { % ... llx lly urx ury | (urx!=0 && llx==urx) || (ury!=0 && lly==ury)
  1685.       % The bounding box is empty and likely incorrect. Don't cache.
  1686.       pop pop pop pop .adjustcharwidth setcharwidth
  1687.     } {
  1688.       6 -2 roll .adjustcharwidth 6 2 roll setcachedevice
  1689.     } ifelse
  1690.   } bdef
  1691.   /Tf {
  1692.     1 index Page /Font rget {
  1693.       resourcefont exch Tf pop
  1694.     }
  1695.     { % Bug 689037
  1696.       (   **** Warning: Tf refers to an unknown resource name: ) pdfformaterror
  1697.       1 index .namestring pdfformaterror
  1698.       ( Assuming it's a font name.\n) pdfformaterror
  1699.       Tf
  1700.     } ifelse
  1701.   } bdef
  1702. end
  1703.  
  1704. end            % pdfdict
  1705. end            % GS_PDF_ProcSet
  1706. .setglobal
  1707.